package com.service.impl;

import com.Factory.FriendApplyResultFactory;
import com.Exception.NormalException.FriendExceptions.FriendAlreadyExistException;
import com.Result.FriendApplyResult;
import com.WebSocket.SocketData;
import com.WebSocket.WebSocket;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.entity.Friend;
import com.entity.FriendApply;
import com.mapper.FriendApplyMapper;
import com.mapper.FriendMapper;
import com.mapper.UserMapper;
import com.service.FriendApplyService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author XTC
 * @since 2024-07-10
 */
@Service
public class FriendApplyServiceImpl extends ServiceImpl<FriendApplyMapper, FriendApply> implements FriendApplyService {
    @Autowired
    private FriendApplyMapper friendApplyMapper;

    @Autowired
    private FriendMapper friendMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private FriendApplyResultFactory friendApplyResultFactory;

    @Override
    public boolean acceptApply(Integer applyId) throws FriendAlreadyExistException {
        FriendApply friendApply = this.friendApplyMapper.selectById(applyId);
        QueryWrapper<Friend> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id1", friendApply.getUserId1())
            .eq("user_id2", friendApply.getUserId2());
        if(this.friendMapper.selectOne(queryWrapper) != null) {
            throw new FriendAlreadyExistException();
        }

        UpdateWrapper<FriendApply> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", applyId).set("status", 1);
        this.friendApplyMapper.update(null, updateWrapper);
        Friend friend = new Friend();
        BeanUtils.copyProperties(friendApply, friend);
        friend.setId(null);
        this.friendMapper.insert(friend);

        // 使其他申请失效
        UpdateWrapper<FriendApply> w2 = new UpdateWrapper<>();

        w2.eq("user_id1", friendApply.getUserId1())
                .eq("user_id2", friendApply.getUserId2())
                .eq("status", 0)
                .ne("id", applyId)
                .set("status", 3);
        this.friendApplyMapper.update(null, w2);
        return true;
    }

    @Override
    public boolean refuseApply(Integer applyId) {
        UpdateWrapper<FriendApply> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", applyId).set("status", 2);
        return this.friendApplyMapper.update(null, updateWrapper) > 0;
    }

    @Override
    public boolean sendFriendApply(FriendApply friendApply) {
        FriendApplyResult friendApplyResult = friendApplyResultFactory.newFriendApplyResult(friendApply);
        SocketData data = new SocketData();
        data.setFriendApply(friendApplyResult);
        data.setType("friend_apply");
        WebSocket.sendOneMessage(String.valueOf(friendApply.getUserId2()), data);
        return true;
    }

    @Override
    public List<FriendApplyResult> getByUserId(Integer userId) {
        QueryWrapper<FriendApply> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id2", userId)
                .orderByDesc("apply_time");
        List<FriendApply> applyList = this.friendApplyMapper.selectList(queryWrapper);
        List<FriendApplyResult> resultList = new ArrayList<>();
        for( FriendApply friendApply : applyList) {
            FriendApplyResult friendApplyResult = friendApplyResultFactory.newFriendApplyResult(friendApply);
            resultList.add(friendApplyResult);
        }
        return resultList;
    }

    @Override
    public boolean sendApplyResult(Integer applyId, boolean result) {
        FriendApply friendApply = this.friendApplyMapper.selectById(applyId);
        FriendApplyResult friendApplyResult = friendApplyResultFactory.newFriendApplyResult(friendApply);
        SocketData data = new SocketData();
        data.setFriendApply(friendApplyResult);
        data.setType("friend_apply");
        WebSocket.sendOneMessage(String.valueOf(friendApply.getUserId1()), data);
        return true;
    }
}
